using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Strategia.GameModels;
using Strategia.Cameras;
using Strategia.Simulation;
using Strategia.Input;

namespace Strategia
{
    public class Engine : Microsoft.Xna.Framework.Game
    {
        #region Declarations
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        float frameRate; // FPS counter
        int STAGE = 0;

        int CURRENT_LIST_NR = 0;

        bool napisalem = false;

        bool isWireFrame;
        bool nowyStan = false;

        CubeDescription cubeDesc;
        List<CubePrimitive> hotel = new List<CubePrimitive>();
        List<List<List<CubePrimitive>>> cubesy = new List<List<List<CubePrimitive>>>();
        CubePrimitive room;
        List<CubePrimitive> wind, heater;
        List<Vector3> Kolizje; // dla tych o stalej temp
        //int currPrimitiveIndex = 0;

        Camera camera;

        MouseState actualMouseState, lastMouseState, desireMouseState;
        KeyboardState actualKeyState, oldKeyState;

        Gui gui;

        Vector3 WinPosL, WinSizeL, WinPosW, WinSizeW;
        Vector3 HeatPosL, HeatSizeL, HeatPosW, HeatSizeW;
        #endregion

        public Engine()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;

            Content.RootDirectory = "Content";

            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        // Called when the game should load its content
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            lastMouseState = Mouse.GetState();

            cubeDesc = new CubeDescription(GraphicsDevice, 1);

            wind = new List<CubePrimitive>();
            heater = new List<CubePrimitive>();
            Kolizje = new List<Vector3>();

            room = new CubePrimitive(cubeDesc, new Vector3(0, 0, 0), new Vector3(0), new Vector3(10 * 100f, 3f * 100f, 7 * 100f), Color.White, 255, GraphicsDevice);
            room.Rozmiar = new Vector3(10.0f, 3.0f, 7.0f);

            WinPosL = new Vector3(-((room.Scale.X / 2) - 5.1f), (room.Scale.Y / 3) / 2, 0);
            WinSizeL = new Vector3(10, 180, 300);
            HeatPosL = new Vector3(-((room.Scale.X / 2) - 5.1f), -(room.Scale.Y / 3), 0);
            HeatSizeL = new Vector3(10, 80, 150);

            gui = new Gui(Content, spriteBatch, GraphicsDevice, this);
            Components.Add(gui);

            Mouse.SetPosition(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2);
            lastMouseState = Mouse.GetState();
            camera = new FreeCamera(new Vector3(0, 0, 2.5f), MathHelper.ToRadians(0), MathHelper.ToRadians(5), GraphicsDevice);

        }

        Color GetLocalTemp(float temp)
        {
            if (temp > Program.initHeatT) return new Color(255, 255, 255, 255);
            if (temp < Program.initWindT) return new Color(0, 0, 0, 255);
            if (Program.initHeatT == Program.initRoomT)
                if (temp == Program.initRoomT) return new Color((temp * Program.roznicaRGB) - 5f * Program.roznicaRGB, 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 0f);
            if (Program.initWindT == Program.initRoomT)
                if (temp == Program.initRoomT) return new Color((temp * Program.roznicaRGB) - 5f * Program.roznicaRGB, 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 0f);
            if (temp == Program.initHeatT) return new Color(255, 0, 0, 200);
            if (temp == Program.initWindT) return new Color(0, 255, 255, 200);
            if (temp == Program.initRoomT) return new Color((temp * Program.roznicaRGB) - 5f * Program.roznicaRGB, 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 0f);
            return new Color((temp * Program.roznicaRGB) - 5f * Program.roznicaRGB, 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 1f - (temp * Program.roznicaRGB - 5f * Program.roznicaRGB), 0.8f);
        }

        void CorrectCubesColor(int l)
        {
            int dX, dY, dZ;
            dX = (int)((int)(room.Rozmiar.X * 100f) / Program.podzialkaX);
            dY = (int)((int)(room.Rozmiar.Y * 100f) / Program.podzialkaY);
            dZ = (int)((int)(room.Rozmiar.Z * 100f) / Program.podzialkaZ);
            for (int i = 1; i <= dX; i++)
            {
                cubesy.Add(new List<List<CubePrimitive>>());
                for (int j = 1; j <= dY; j++)
                {
                    cubesy[i - 1].Add(new List<CubePrimitive>());
                    for (int k = 1; k <= dZ; k++)
                    {
                        Color co = GetLocalTemp(Program.obl[l][i - 1][j - 1][k - 1]);

                        cubesy[i - 1][j - 1][k - 1].color = co;
                    }
                }
            }
        }

        protected override void UnloadContent()
        {
        }

        // Called when the game should update itself
        int n = 0;
        int licznikOkien = 0;
        int licznikGrzej = 0;
        bool obliczam = false;
        protected override void Update(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            actualMouseState = Mouse.GetState();

            #region STAGE0
            if (STAGE == 0)
            {
                gui.Info1 = "USTAWIENIA POMIESZCZENIA";
                poz = false;
                if (poz) gui.Info3 = "Zmiana POLOZENIA";
                else gui.Info3 = "Zmiana ROZMIARU";
                SetFocus(room);
            }
            #endregion
            #region STAGE1
            if (STAGE == 1)
            {
                gui.Info1 = "USTAWIENIA OKIEN";
                if (poz) gui.Info3 = "Zmiana POLOZENIA";
                else gui.Info3 = "Zmiana ROZMIARU";
                if (wind.Count() == 0)
                {
                    wind.Add(new CubePrimitive(cubeDesc, WinPosL, new Vector3(0), WinSizeL, Color.Blue, 200, GraphicsDevice));
                    wind[0].Rozmiar = new Vector3(0.1f, 1.8f, 3.0f);
                }

                if (Keyboard.GetState().IsKeyDown(Keys.P) || gui.Clicked(actualMouseState, lastMouseState) == 8)
                {
                    if (n == 0)
                    {
                        licznikOkien++;
                        wind.Add(new CubePrimitive(cubeDesc, WinPosL, new Vector3(0), WinSizeL, Color.Blue, 200, GraphicsDevice));
                        wind[licznikOkien].Rozmiar = new Vector3(0.1f, 1.8f, 3.0f);
                    }

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }
                if (!nowyStan) SetFocus(wind[licznikOkien]);
                else nowyStan = false;
            }
            #endregion
            #region STAGE2
            if (STAGE == 2)
            {
                gui.Info1 = "USTAWIENIA GRZEJNIKOW";
                if (poz) gui.Info3 = "Zmiana POLOZENIA";
                else gui.Info3 = "Zmiana ROZMIARU";
                if (heater.Count() == 0)
                {
                    heater.Add(new CubePrimitive(cubeDesc, HeatPosL, new Vector3(0), HeatSizeL, Color.Red, 200, GraphicsDevice));
                    heater[0].Rozmiar = new Vector3(0.1f, 0.8f, 1.5f);
                }

                if (Keyboard.GetState().IsKeyDown(Keys.P) || gui.Clicked(actualMouseState, lastMouseState) == 8)
                {
                    if (n == 0)
                    {
                        licznikGrzej++;
                        heater.Add(new CubePrimitive(cubeDesc, HeatPosL, new Vector3(0), HeatSizeL, Color.Red, 200, GraphicsDevice));
                        heater[licznikGrzej].Rozmiar = new Vector3(0.1f, 0.8f, 1.5f);
                    }

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }

                if (!nowyStan) SetFocus(heater[licznikGrzej]);
                else nowyStan = false;
            }
            #endregion
            #region STAGE3
            if (STAGE == 3)
            {
                gui.Info1 = "WYKONYWANIE OBLICZEN";
                gui.Info2 = "PROSZE CZEKAC";
                gui.zmiana = true;
                if (!obliczam)
                {
                    obliczam = true;

                    FillWithCubes();
                    DoMath();

                    STAGE = 4;
                }
                nowyStan = false;
            }
            #endregion
            #region STAGE4
            if (STAGE == 4)
            {
                gui.Info1 = "Stan nr: " + (CURRENT_LIST_NR + 1).ToString();
                gui.Info2 = "Liczba stanow: " + Program.obl.Count().ToString();
                gui.Info3 = "Zmiana stanu [L,P] Wlaczanie swiatla [G,D] Wylaczanie/wlaczanie modeli okien i grzejnikow [Num1,Num4]";

                if (Keyboard.GetState().IsKeyDown(Keys.Right) || gui.Clicked(actualMouseState, lastMouseState) == 3)
                {
                    if (n == 0)
                        if ((CURRENT_LIST_NR + 1) < Program.obl.Count())
                            CURRENT_LIST_NR++;
                    CorrectCubesColor(CURRENT_LIST_NR);

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.Left) || gui.Clicked(actualMouseState, lastMouseState) == 1)
                {
                    if (n == 0)
                        if ((CURRENT_LIST_NR - 1) > -1)
                            CURRENT_LIST_NR--;
                    CorrectCubesColor(CURRENT_LIST_NR);

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.OemPeriod) || gui.Clicked(actualMouseState, lastMouseState) == 12)
                {
                    if (n == 0)
                        if ((CURRENT_LIST_NR + 2) < Program.obl.Count())
                            CURRENT_LIST_NR = CURRENT_LIST_NR + 2;
                    CorrectCubesColor(CURRENT_LIST_NR);

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.OemComma) || gui.Clicked(actualMouseState, lastMouseState) == 11)
                {
                    if (n == 0)
                        if ((CURRENT_LIST_NR - 2) > -1)
                            CURRENT_LIST_NR = CURRENT_LIST_NR - 2;
                    CorrectCubesColor(CURRENT_LIST_NR);

                    n++;
                    if (n == 5) n = 0;

                    if (napisalem)
                        napisalem = false;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.Home) || gui.Clicked(actualMouseState, lastMouseState) == 13)
                {
                    if (n == 0)
                    {
                        CURRENT_LIST_NR = 0;
                        CorrectCubesColor(CURRENT_LIST_NR);
                    }

                    n++;
                    if (n == 5) n = 0;
                }
                else if (Keyboard.GetState().IsKeyDown(Keys.End) || gui.Clicked(actualMouseState, lastMouseState) == 14)
                {
                    if (n == 0)
                    {
                        CURRENT_LIST_NR = Program.obl.Count() - 1;
                        CorrectCubesColor(CURRENT_LIST_NR);
                    }

                    n++;
                    if (n == 5) n = 0;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.Up) || gui.Clicked(actualMouseState, lastMouseState) == 4)
                    cubeDesc.basicEffect.LightingEnabled = true;
                if (Keyboard.GetState().IsKeyDown(Keys.Down) || gui.Clicked(actualMouseState, lastMouseState) == 2)
                    cubeDesc.basicEffect.LightingEnabled = false;
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad4) || gui.Clicked(actualMouseState, lastMouseState) == 6)
                {
                    if (n == 0)
                    {
                        foreach (CubePrimitive wnd in wind)
                            wnd.DrawMe = true;
                        foreach (CubePrimitive het in heater)
                            het.DrawMe = true;
                    }
                    n++;
                    if (n == 5) n = 0;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad1) || gui.Clicked(actualMouseState, lastMouseState) == 5)
                {
                    if (n == 0)
                    {
                        foreach (CubePrimitive wnd in wind)
                            wnd.DrawMe = false;
                        foreach (CubePrimitive het in heater)
                            het.DrawMe = false;
                    }
                    n++;
                    if (n == 5) n = 0;
                }
                nowyStan = false;
            }
            #endregion

            this.Window.Title = "Cieplo [FPS: " + (int)frameRate + "]";

            if (actualMouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released)
            {
                this.IsMouseVisible = false;
                desireMouseState = lastMouseState;
                Mouse.SetPosition(GraphicsDevice.PresentationParameters.BackBufferWidth / 2, GraphicsDevice.PresentationParameters.BackBufferHeight / 2);
            }
            else if (actualMouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Pressed)
            {
                ((FreeCamera)camera).Fly(gameTime);
            }
            else if (actualMouseState.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed)
            {
                Mouse.SetPosition(desireMouseState.X, desireMouseState.Y);
            }
            else
                this.IsMouseVisible = true;

            lastMouseState = actualMouseState;
            base.Update(gameTime);
        }

        bool bylo = false;
        void FillWithCubes()
        {
            int dX, dY, dZ;
            dX = (int)((int)(room.Rozmiar.X * 100f) / Program.podzialkaX);
            dY = (int)((int)(room.Rozmiar.Y * 100f) / Program.podzialkaY);
            dZ = (int)((int)(room.Rozmiar.Z * 100f) / Program.podzialkaZ);

            Program.obl.Add(new List<List<List<float>>>());
            for (int i = 1; i <= dX; i++)
            {
                Program.obl[0].Add(new List<List<float>>());
                cubesy.Add(new List<List<CubePrimitive>>());
                for (int j = 1; j <= dY; j++)
                {
                    Program.obl[0][i - 1].Add(new List<float>());
                    cubesy[i - 1].Add(new List<CubePrimitive>());
                    for (int k = 1; k <= dZ; k++)
                    {
                        Color co = Color.White;
                        cubesy[i - 1][j - 1].Add(new CubePrimitive(cubeDesc, new Vector3((-((room.Rozmiar.X * 100f) / 2) - (Program.podzialkaX / 2)) + (i * Program.podzialkaX),
                            (-((room.Rozmiar.Y * 100f) / 2) - (Program.podzialkaY / 2)) + (j * Program.podzialkaY),
                            (((room.Rozmiar.Z * 100f) / 2) + (Program.podzialkaZ / 2)) - (k * Program.podzialkaZ)),
                            new Vector3(0), new Vector3(1f * (float)Program.podzialkaX, 1f * (float)Program.podzialkaY, 1f * (float)Program.podzialkaZ), Color.White, 0, GraphicsDevice));

                        foreach (CubePrimitive wnd in wind)
                        {
                            if (wnd.boundingBox.Contains(cubesy[i - 1][j - 1][k - 1].boundingBox) == ContainmentType.Intersects
                                || wnd.boundingBox.Contains(cubesy[i - 1][j - 1][k - 1].boundingBox) == ContainmentType.Contains)
                            {
                                co = GetLocalTemp(Program.initWindT);
                                Program.obl[0][i - 1][j - 1].Add(Program.initWindT);
                                if(wnd.CieploStale) Kolizje.Add(new Vector3(i - 1, j - 1, k - 1));
                                bylo = true;
                            }
                        }

                        foreach (CubePrimitive het in heater)
                        {
                            if (het.boundingBox.Contains(cubesy[i - 1][j - 1][k - 1].boundingBox) == ContainmentType.Intersects
                                || het.boundingBox.Contains(cubesy[i - 1][j - 1][k - 1].boundingBox) == ContainmentType.Contains)
                            {
                                co = GetLocalTemp(Program.initHeatT);
                                Program.obl[0][i - 1][j - 1].Add(Program.initHeatT);
                                if (het.CieploStale) Kolizje.Add(new Vector3(i - 1, j - 1, k - 1));
                                bylo = true;
                            }
                        }

                        if (!bylo)
                        {
                            co = GetLocalTemp(Program.initRoomT);
                            Program.obl[0][i - 1][j - 1].Add(Program.initRoomT);
                        }
                        bylo = false;
                        cubesy[i - 1][j - 1][k - 1].color = co;
                    }
                }
            }
        }

        void DoMath()
        {
            int dX, dY, dZ;
            dX = (int)((int)(room.Rozmiar.X * 100f) / Program.podzialkaX);
            dY = (int)((int)(room.Rozmiar.Y * 100f) / Program.podzialkaY);
            dZ = (int)((int)(room.Rozmiar.Z * 100f) / Program.podzialkaZ);

            Maths maths = new Maths(1, dX, 1, dY, 1, dZ);

            int timeStamp = Program.timeOfSimulation / Program.deltaTime;

            for (int l = 1; l <= timeStamp; l++)
            {
                Program.obl.Add(new List<List<List<float>>>());
                for (int i = 1; i <= dX; i++)
                {
                    Program.obl[l].Add(new List<List<float>>());
                    for (int j = 1; j <= dY; j++)
                    {
                        Program.obl[l][i - 1].Add(new List<float>());
                        for (int k = 1; k <= dZ; k++)
                        {
                            if (Kolizje.Contains(new Vector3(i - 1, j - 1, k - 1)))
                            {
                                Program.obl[l][i - 1][j - 1].Add(Program.obl[l - 1][i - 1][j - 1][k - 1]);
                            }
                            else
                            {
                                Program.obl[l][i - 1][j - 1].Add(maths.T_cella_nowa(i, j, k, Program.obl[l - 1]));
                            }
                        }
                    }
                }
            }
        }

        bool poz = true;
        bool SetFocus(CubePrimitive cub)
        {
            gui.pozX = cub.Position.X;
            gui.pozY = cub.Position.Y;
            gui.pozZ = cub.Position.Z;

            gui.W = cub.Rozmiar.X;
            gui.H = cub.Rozmiar.Y;
            gui.L = cub.Rozmiar.Z;

            bool dalej = false;

            if (cub.CieploStale) gui.Info2 = "Obiekt bedzie utrzymywal cieplo";
            if (!cub.CieploStale) gui.Info2 = "Obiekt posiada cieplo poczatkowe";

            if (Keyboard.GetState().IsKeyDown(Keys.Left) || gui.Clicked(actualMouseState, lastMouseState) == 1)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.X += 10;
                    }
                    else
                    {
                        cub.Scale.X += 10;
                        cub.Rozmiar.X += 0.1f;
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.OemComma) || gui.Clicked(actualMouseState, lastMouseState) == 11)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.X += 20;
                    }
                    else
                    {
                        cub.Scale.X += 20;
                        cub.Rozmiar.X += 0.2f;
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Right) || gui.Clicked(actualMouseState, lastMouseState) == 3)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.X -= 10;
                    }
                    else
                    {
                        if (cub.Rozmiar.X - 0.1f >= 0.1)
                        {
                            cub.Scale.X -= 10;
                            cub.Rozmiar.X -= 0.1f;
                        }
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.OemPeriod) || gui.Clicked(actualMouseState, lastMouseState) == 12)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.X -= 20;
                    }
                    else
                    {
                        if (cub.Rozmiar.X - 0.2f >= 0.2)
                        {
                            cub.Scale.X -= 20;
                            cub.Rozmiar.X -= 0.2f;
                        }
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Up) || gui.Clicked(actualMouseState, lastMouseState) == 4)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.Z += 10;
                    }
                    else
                    {
                        cub.Scale.Z += 10;
                        cub.Rozmiar.Z += 0.1f;
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Down) || gui.Clicked(actualMouseState, lastMouseState) == 2)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.Z -= 10;
                    }
                    else
                    {
                        if (cub.Rozmiar.Z - 0.1f >= 0.1)
                        {
                            cub.Scale.Z -= 10;
                            cub.Rozmiar.Z -= 0.1f;
                        }
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.NumPad4) || gui.Clicked(actualMouseState, lastMouseState) == 6)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.Y += 10;
                    }
                    else
                    {
                        cub.Scale.Y += 10;
                        cub.Rozmiar.Y += 0.1f;
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.NumPad1) || gui.Clicked(actualMouseState, lastMouseState) == 5)
            {
                if (n == 0)
                {
                    if (poz)
                    {
                        cub.Position.Y -= 10;
                    }
                    else
                    {
                        if (cub.Rozmiar.Y - 0.1f >= 0.1)
                        {
                            cub.Scale.Y -= 10;
                            cub.Rozmiar.Y -= 0.1f;
                        }
                    }
                    cub.UpdateBBox();
                }

                n++;
                if (n == 5) n = 0;

                if (napisalem)
                    napisalem = false;
            }
            actualKeyState = Keyboard.GetState();
            if ((actualKeyState.IsKeyUp(Keys.NumPad5) && oldKeyState.IsKeyDown(Keys.NumPad5)) || gui.Clicked(actualMouseState, lastMouseState) == 7)
            {
                poz = !poz;
                if (poz) Console.WriteLine("Ustawiasz POZYCJE");
                else Console.WriteLine("Ustawiasz ROZMIAR");
            }

            if ((actualKeyState.IsKeyUp(Keys.U) && oldKeyState.IsKeyDown(Keys.U)) || gui.Clicked(actualMouseState, lastMouseState) == 10)
            {
                cub.CieploStale = !cub.CieploStale;
            }

            if ((actualKeyState.IsKeyUp(Keys.Enter) && oldKeyState.IsKeyDown(Keys.Enter)) || gui.Clicked(actualMouseState, lastMouseState) == 9)
            {
                if (!nowyStan)
                {
                    nowyStan = true;
                    dalej = true;
                    STAGE++;
                    Console.WriteLine(STAGE);
                }
            }
            oldKeyState = actualKeyState;
            return dalej;
        }

        // Called when the game should draw itself
        protected override void Draw(GameTime gameTime)
        {
            //renderer.Draw();

            GraphicsDevice.Clear(Color.Black);

            if (STAGE == 0)
            {
                if (camera.BoundingVolumeIsInView(room.boundingBox))
                {
                    room.DrawBox(camera.View, camera.Projection);
                }
            }
            else if (STAGE == 1)
            {
                if (camera.BoundingVolumeIsInView(room.boundingBox))
                {
                    room.Draw(camera.View, camera.Projection, false);
                    //room.DrawBox(camera.View, camera.Projection);
                }

                for (int i = 0; i < wind.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(wind[i].boundingBox))
                    {
                        if (i == licznikOkien)
                            wind[i].DrawBox(camera.View, camera.Projection);
                        else
                        {
                            wind[i].Draw(camera.View, camera.Projection, true);
                            //wind[i].DrawBox(camera.View, camera.Projection);
                        }
                    }
                }
            }
            else if (STAGE == 2)
            {
                if (camera.BoundingVolumeIsInView(room.boundingBox))
                {
                    room.Draw(camera.View, camera.Projection, false);
                    //room.DrawBox(camera.View, camera.Projection);
                }

                for (int i = 0; i < wind.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(wind[i].boundingBox))
                    {
                        wind[i].Draw(camera.View, camera.Projection, true);
                        //wind[i].DrawBox(camera.View, camera.Projection);
                    }
                }

                for (int i = 0; i < heater.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(heater[i].boundingBox))
                    {
                        if (i == licznikGrzej)
                            heater[i].DrawBox(camera.View, camera.Projection);
                        else
                        {
                            heater[i].Draw(camera.View, camera.Projection, true);
                            //heater[i].DrawBox(camera.View, camera.Projection);
                        }
                    }
                }
            }
            else if (STAGE == 3)
            {
                if (camera.BoundingVolumeIsInView(room.boundingBox))
                {
                    room.Draw(camera.View, camera.Projection, false);
                    //room.DrawBox(camera.View, camera.Projection);
                }

                for (int i = 0; i < wind.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(wind[i].boundingBox))
                    {
                        wind[i].Draw(camera.View, camera.Projection, true);
                        //wind[i].DrawBox(camera.View, camera.Projection);
                    }
                }

                for (int i = 0; i < heater.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(heater[i].boundingBox))
                    {
                        heater[i].Draw(camera.View, camera.Projection, true);
                        //heater[i].DrawBox(camera.View, camera.Projection);
                    }
                }
            }
            else if (STAGE == 4)
            {
                if (camera.BoundingVolumeIsInView(room.boundingBox))
                {
                    room.Draw(camera.View, camera.Projection, false);
                    //room.DrawBox(camera.View, camera.Projection);
                }

                for (int i = 0; i < wind.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(wind[i].boundingBox))
                    {
                        if (wind[i].CieploStale)
                            wind[i].Draw(camera.View, camera.Projection, true);
                        else
                            wind[i].DrawBox(camera.View, camera.Projection);
                    }
                }

                for (int i = 0; i < heater.Count(); i++)
                {
                    if (camera.BoundingVolumeIsInView(heater[i].boundingBox))
                    {
                        if(heater[i].CieploStale)
                            heater[i].Draw(camera.View, camera.Projection, true);
                        else
                            heater[i].DrawBox(camera.View, camera.Projection);
                    }
                }

                for (int i = 0; i < cubesy.Count(); i++)
                    for (int j = 0; j < cubesy[i].Count(); j++)
                        for (int k = 0; k < cubesy[i][j].Count(); k++)
                            if (camera.BoundingVolumeIsInView(cubesy[i][j][k].boundingBox))
                            {
                                if (cubesy[i][j][k].color.A > 0)
                                    cubesy[i][j][k].Draw(camera.View, camera.Projection, true);
                            }
            }

            // FPS count
            frameRate = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;

            base.Draw(gameTime);
        }
    }
}
